# Unicode 编码的具体实现方式 urf-8, utf-16, utf-32
# 现在程序员都喜欢utf-8作为编码方式
# 一个英文字符占用一个字节
# 一个汉字字符占用三个字节 --》 不友好啊

# 中国自己开发的编码方式 --》 gbk gb2312
# 一个中文字符占2个字节
# python2 默认编码是ASCII --》所以第一行要加上 #encoding：utf-8
# python3 默认编码是utf-8

# ----------------------------------------------
# 引出两个函数 encode为编码 decode为解码
str = "王"

print(str.encode("utf-8"))
# b'\xe7\x8e\x8b'
# b --》表示字节型 有三个字节，以十六进制存储
print(str.encode("utf-8").decode("utf-8"))

print(str.encode("gb2312"))
# b'\xcd\xf5'
print(str.encode("gb2312").decode("gb2312"))
# 以什么编码存储就用什么编码转换

# ------------------------------------------------
# 文件读取
# open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
# 默认模式为 r 读模式
fp = open("1.txt", encoding="utf-8")
print(fp.read())
# 参数encoding="" --》 指定文件打开的编码格式
# 这里需要注意的是例如如果文件的utf-8创建的，用open（）函数打开是指定其他编码方式，会错误

# 查看文件的编码格式
import chardet
# mode = rb --》表示由二进制打开文件
fp = open("1.txt", "rb")
print(chardet.detect(fp.read()))

# -------------------------------------------------
# 文件写入
# flush()清空缓存区的数据

# # 写模式
# fp = open("1.txt", 'w', encoding="utf-8")
# fp.write("ahhhhhhh")
# fp.flush()
# fp = open("1.txt", encoding="utf-8")
# print(fp.read())
# fp.close()

# # 追加模式
# fp = open("1.txt", 'a', encoding="utf-8")
# fp.write("ahhhhhhh")
# fp.close()
# fp = open("1.txt", encoding="utf-8")
# print(fp.read())

# # 创建新文件，并写入内容
# fp = open("1.txt", 'x')
# fp.write("abscsd")
# fp.flush()
# fp = open("1.txt")
# print(fp.read())

# -------------------------------------------------
# with语法 自动帮你关闭文件连接 属于语法糖：就是简化某种语法，对原来的语法功能没有影响
with open("1.txt") as fp:
    print(fp.read())

# -------------------------------------------------
with open("2.txt", encoding="utf-8") as fp:
    print(fp.read())
    # 发现第二个read（）没有输出，这里文件读的时候会有指针
    print(fp.read())
    #告诉你文件指针位置
    print(fp.tell())
    #指定文件指针位置 seek(cookie, whence=0)
    #                   cookie --》偏移值  表示指针所在字节数，可正可负
    #                   whence --》0 表示开始的位置
    #                          --》1 表示当前位置
    #                          --》2 表示结束位置
    # 默认指针指定0
    fp.seek(0)
    # 读当前指针到指定位置
    print(fp.read(2))

    fp.seek(0)
    # 读当前指针到这一行末
    print(fp.readline())

    fp.seek(0)
    # 读当前指针开始到指定位置的所在行都输出出来，插入到列表里返回
    print(fp.readlines())
    # 由以下两个例子知道换行符不算一个字符
    fp.seek(0)
    print(fp.readlines(3))
    fp.seek(0)
    print(fp.readlines(4))
    fp.seek(0)
    print(fp.read(2))
    print(fp.readlines(4))

    # for 循环
    fp.seek(0)
    for line in fp:
        print(line)
    fp.seek(0)
    for line in fp:
        print(id(line))

# 为了兼顾效率和内存我们会使用readlines（）去读取文件
# 小练习：读取一个文件，显示除了以井号开头的行以外的所有行
print("小练习：")
with open("3.txt", encoding="utf=8") as fp:
    for line in fp:
        if line[0] == '#':
            continue
        else:
            print(line)
    fp.seek(0)
    for line in fp:
        # startswitch('#')查找以井号开头
        if line.startswith('#'):
            continue
        else:
            print(line)

# --------------------------------------------------
#### 为什么不实时写入磁盘里？
# 硬盘是慢设备，频率增加会加大磁盘的写入压力，产生瓶颈就是要等待
# 以下内容必须在linux或这windows里cmd的python上才能看出,pycharm会出现不同情况

## buffering=
# 0 => 实时写入
# 1 => 行缓存 => \n
# 其他数字n => 缓存区大小n=2*4096字节

# 行缓存
fp = open("4.txt", 'w+', buffering=1)
fp.write("aaaa")
fp = open("4.txt", 'w+', buffering=1)
fp.write("aaaa\n")
